package cn.iocoder.an.module.mold.service.rechecktobe;

import cn.iocoder.an.module.mold.controller.admin.rechecktobe.vo.RecheckTobeDispatchVO;
import cn.iocoder.an.module.mold.controller.admin.rechecktask2item.vo.RecheckTask2itemSaveReqVO;
import cn.iocoder.an.module.mold.controller.admin.rechecktobe.vo.RecheckTobeAuditVO;
import cn.iocoder.an.module.mold.dal.dataobject.account.AccountDO;
import cn.iocoder.an.module.mold.dal.dataobject.rechecktask.RecheckTaskDO;
import cn.iocoder.an.module.mold.dal.dataobject.rechecktobe.RecheckTobeDO;
import cn.iocoder.an.module.mold.dal.dataobject.recheckcategory.RecheckCategoryDO;
import cn.iocoder.an.module.mold.dal.dataobject.recheckstatics.RecheckStaticsDO;
import cn.iocoder.an.module.mold.dal.dataobject.rechecktask2item.RecheckTask2itemDO;
import cn.iocoder.an.module.mold.dal.mysql.account.AccountMapper;
import cn.iocoder.an.module.mold.dal.mysql.rechecktask.RecheckTaskMapper;
import cn.iocoder.an.module.mold.dal.mysql.recheckcategory.RecheckCategoryMapper;
import cn.iocoder.an.module.mold.dal.mysql.recheckstatics.RecheckStaticsMapper;
import cn.iocoder.an.module.mold.dal.mysql.rechecktask2item.RecheckTask2itemMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;
import cn.iocoder.an.module.mold.controller.admin.rechecktobe.vo.*;
import cn.iocoder.an.framework.common.pojo.PageResult;
import cn.iocoder.an.framework.common.util.object.BeanUtils;

import cn.iocoder.an.module.mold.dal.mysql.rechecktobe.RecheckTobeMapper;

import static cn.iocoder.an.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.an.module.mold.enums.ErrorCodeConstants.*;

/**
 * 待复检 Service 实现类
 *
 * @author ykk
 */
@Service
@Validated
public class RecheckTobeServiceImpl implements RecheckTobeService {

    @Resource
    private RecheckTobeMapper recheckTobeMapper;

    @Resource
    private AccountMapper accountMapper;


    @Resource
    private RecheckTaskMapper recheckTaskMapper;

    @Resource
    private RecheckTask2itemMapper recheckTask2itemMapper;

    @Resource
    private RecheckCategoryMapper recheckCategoryMapper;

    @Resource
    private RecheckStaticsMapper recheckStaticsMapper;


    @Override
    public Long createRecheckTobe(RecheckTobeSaveReqVO createReqVO) {
        RecheckTobeDO recheckTobe = BeanUtils.toBean(createReqVO, RecheckTobeDO.class);
        if (existsByAccountId(createReqVO.getAccountId())) {
            throw exception(RECHECK_TOBE_MOLD_EXISTS);
        }

        //建议直接查询模具状态，然后
        AccountDO accountDO = accountMapper.selectById(recheckTobe.getAccountId());
        RecheckCategoryDO category = recheckCategoryMapper.selectById(recheckTobe.getRecheckId());

        recheckTobe.setDrawingNoId(accountDO.getDrawingNoId());
        //设置上次保养时间LocalDateTime
        recheckTobe.setLastRecheckTime(accountDO.getLastRecheckTime());

        //状态管理  待派工 需要与字段对应
        recheckTobe.setStatus(1);
        recheckTobe.setRemindF(0);
        // 插入
        recheckTobeMapper.insert(recheckTobe);
        // 返回
        return recheckTobe.getId();
    }

    public Boolean existsByAccountId(Long accountId) {
        // 使用 QueryWrapper 进行查询
        QueryWrapper<RecheckTobeDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("account_id", accountId);
        return recheckTobeMapper.selectCount(queryWrapper) > 0;
    }


    @Override
    public void updateRecheckTobe(RecheckTobeSaveReqVO updateReqVO) {
        // 校验存在
        validateRecheckTobeExists(updateReqVO.getId());
        // 更新
        RecheckTobeDO updateObj = BeanUtils.toBean(updateReqVO, RecheckTobeDO.class);
        recheckTobeMapper.updateById(updateObj);
    }

    @Override
    public void deleteRecheckTobe(Long id) {
        // 校验存在
        validateRecheckTobeExists(id);
        // 删除
       // recheckTobeMapper.deleteById(id);
        recheckTobeMapper.forceDeleteById(id);
    }

    @Override
        public void deleteRecheckTobeListByIds(List<Long> ids) {
        // 删除
        recheckTobeMapper.deleteByIds(ids);
        }


    private void validateRecheckTobeExists(Long id) {
        if (recheckTobeMapper.selectById(id) == null) {
            throw exception(RECHECK_TOBE_NOT_EXISTS);
        }
    }

    @Override
    public RecheckTobeDO getRecheckTobe(Long id) {
        return recheckTobeMapper.selectById(id);
    }

    @Override
    public PageResult<RecheckTobeDO> getRecheckTobePage(RecheckTobePageReqVO pageReqVO) {
        return recheckTobeMapper.selectPage(pageReqVO);
    }


    @Override
    public Boolean dispatch(RecheckTobeDispatchVO dispatch) {
        //待复检任务Id
        long recheckTobeId = dispatch.getId();
        Long assigneerId = dispatch.getAssigneerId();

        RecheckTobeDO recheckTobe = recheckTobeMapper.selectById(recheckTobeId);
        AccountDO accountDO = accountMapper.selectById(recheckTobe.getAccountId());

        RecheckTaskDO recheckTask = new RecheckTaskDO();
        recheckTask.setCode(UUID.randomUUID().toString());
        recheckTask.setDrawingNoId(recheckTobe.getDrawingNoId());
        recheckTask.setAccountId(recheckTobe.getAccountId());
        recheckTask.setRecheckId(recheckTobe.getRecheckId());
        recheckTask.setAssigneerId(assigneerId);
        recheckTask.setNextRecheckTime(accountDO.getNextRecheckTime());
        recheckTask.setTaskCreateTime(LocalDateTime.now());
        recheckTask.setStatus(2);
        //创建task
        recheckTaskMapper.insert(recheckTask);
        //更新
        recheckTobe.setTaskId(recheckTask.getId());
        recheckTobe.setStatus(2);
        recheckTobeMapper.updateById(recheckTobe);
        return true;
    }


    public Boolean cancelDispatch(Long id) {
        RecheckTobeDO recheckTobe = recheckTobeMapper.selectById(id);
        if (recheckTobe.getStatus() > 2) {
            throw exception(UPKEEP_TASK_ALREADY_RECEIVED);
        }
        //判断recheckTobe
        //删除任务
        recheckTaskMapper.deleteById(recheckTobe.getTaskId());

        //修改待复检任务状态
        recheckTobe.setTaskId(null);
        recheckTobe.setStatus(1);
        //更新
        recheckTobeMapper.updateById(recheckTobe);
        return true;
    }



    public Boolean audit(RecheckTobeAuditVO audit) {
        RecheckTaskDO task = recheckTaskMapper.selectById(audit.getId());
        RecheckTobeDO tobe = recheckTobeMapper.selectOne(new LambdaQueryWrapper<RecheckTobeDO>().eq(RecheckTobeDO::getTaskId, task.getId()));
        task.setActualStartTime(audit.getActualStartTime());
        task.setActualEndTime(audit.getActualEndTime());
        task.setActualExecutionDuration(audit.getActualExecutionDuration());
        task.setAuditDescription(audit.getAuditDescription());
        //这里需要先删除task2item
        recheckTask2itemMapper.delete(new LambdaQueryWrapper<RecheckTask2itemDO>()
                .eq(RecheckTask2itemDO::getTaskId, task.getId()));
        //循环插入items
        if (audit.getRecheckItems().size() > 0) {
            for (RecheckTask2itemSaveReqVO item : audit.getRecheckItems()) {
                recheckTask2itemMapper.insert(BeanUtils.toBean(item, RecheckTask2itemDO.class));
            }
        }
        task.setStatus(6);
        recheckTaskMapper.updateById(task);
        tobe.setStatus(6);
        recheckTobeMapper.updateById(tobe);
        //todo :审核完成后  需要同步更新模具的复检状态
        AccountDO accountDO = accountMapper.selectById(tobe.getAccountId());
        RecheckCategoryDO recheckCategoryDO = recheckCategoryMapper.selectById(accountDO.getRecheckId());
        //上次复检日期
        accountDO.setLastRecheckTime(task.getActualEndTime());
        //下次复检日期
        accountDO.setNextRecheckTime(task.getActualEndTime().plusDays(recheckCategoryDO.getRecheckPeriod()));
        accountMapper.updateById(accountDO);
        //统计
        RecheckStaticsDO staticsDO = new RecheckStaticsDO();
        staticsDO.setAccountId(accountDO.getId());
        staticsDO.setDrawingNoId(task.getDrawingNoId());
        staticsDO.setRecheckId(task.getRecheckId());
        //获取原统计记录
        if (recheckStaticsMapper.selectCount(new LambdaQueryWrapper<RecheckStaticsDO>().eq(RecheckStaticsDO::getAccountId, accountDO.getId())) > 0) {
            staticsDO = recheckStaticsMapper.selectOne(new LambdaQueryWrapper<RecheckStaticsDO>().eq(RecheckStaticsDO::getAccountId, accountDO.getId()));
            staticsDO.setRecheckCounts(staticsDO.getRecheckCounts() + 1);
            staticsDO.setRecheckTotalTime(staticsDO.getRecheckTotalTime()+ task.getActualExecutionDuration() );
        }else{
            staticsDO.setRecheckCounts(1L);
            staticsDO.setRecheckTotalTime(task.getActualExecutionDuration());
        }

        recheckStaticsMapper.insertOrUpdate(staticsDO);
        deleteRecheckTobe(tobe.getId());
        return true;
    }

}